using System;
using System.Collections.Generic;
using System.Linq;
using IBS.Model;

namespace IBS.Bll
{
    public static class CurrencyConverter
    {
        public struct ConversionResult 
        {
            public decimal Amount { get; set; }  // in target currency
            public decimal Premium { get; set; } // in base currency
            
            public bool IsSuccessfull { get; set; }
            public string Description { get; set; }
        }
        
        // convert transaction amount from one currency to another
        public static ConversionResult Convert(decimal amount, Currency from, Currency to, DateTime date)
        {
            if(from == null || to == null) 
            {
                return new ConversionResult { 
                    Description = "currencies should be not null",
                };
            }

            if(from.ISO == to.ISO) 
            {
                return new ConversionResult {
                    Amount = amount,
                    IsSuccessfull = true,
                };
            }

            var toRate = to.CurrencyExchangeRate.OrderByDescending(r=>r.Date).FirstOrDefault();
            var fromRate = from.CurrencyExchangeRate.OrderByDescending(r=>r.Date).FirstOrDefault();
            if (toRate == null)
            {
                return new ConversionResult {
                    Description = String.Format("{0}: cannot find an exchange rate for {1}", date.ToShortDateString(), to.ISO)
                };
            }
            if(fromRate == null)
            {
                return new ConversionResult {
                    Description = String.Format("{0}: cannot find an exchange rate for {1}", date.ToShortDateString(), from.ISO)
                };
            }
            if (toRate.BidRate == 0 || toRate.AskRate == 0 || fromRate.BidRate == 0 || fromRate.AskRate == 0) 
            {
                return new ConversionResult {
                    Description = String.Format("{0} and {1} conversion rates should be different from zero ({1})", 
                                                from.ISO, to.ISO, date.ToShortDateString()),
                };
            }
            
            var targetAmount = amount * fromRate.BidRate / toRate.AskRate;
            var premium = amount * (fromRate.AskRate - fromRate.BidRate) 
                + targetAmount * (toRate.AskRate - toRate.BidRate);
            return new ConversionResult {
                Amount  = targetAmount,
                Premium = premium,
                IsSuccessfull = true,
            };
        }
    }
}

